package com.china.mobile.ai.service.impl;

import cn.hutool.core.date.DateUtil;
import com.china.mobile.ai.constants.Constant;
import com.china.mobile.ai.service.ChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

/** AI对话业务实现
 * @author: lxr
 * @Date: 2025/10/13 23:38
 * @Description:
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ChatServiceImpl implements ChatService {
    private final ChatClient chatClient;
    private final VectorStore vectorStore;
    /**
     * chat
     * @param: question - [String]用户输入的问题内容
     * @param: sessionId - [String]会话id
     * @return: Flux<String> 包含逐条响应内容和结束标记的响应流，每个元素为字符串格式
     */
    @Override
    public Flux<String> chat(String question, String sessionId) {
        // 创建搜索请求，用于搜索相关文档
        SearchRequest searchRequest = SearchRequest.builder()
                // 设置查询条件
                .query(question)
                // 设置最多返回的文档数量
                .topK(3)
                .build();
        // 调用聊天客户端生成流式响应内容
        return chatClient.prompt()
                .user(question)
                .system(Constant.SYSTEM_ROLE)
                // 设置系统角色参数
                .system(prompt -> prompt.param("now", DateUtil.now()))
                // 设置会话记忆参数
                .advisors(advisors -> advisors
                        .param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId)
                        // 设置RAG的Advisor
                        .advisors(new QuestionAnswerAdvisor(vectorStore,searchRequest)))
                .stream()
                .content()
                //记录每次响应的内容
                .doOnNext(content -> log.info("question:{} ,content: {}", question, content))
                // 在流结束时添加结束标记
                .concatWith(Flux.just("[END]"));

    }


}
